#ifndef __LSTATICARRAY_H__
#define __LSTATICARRAY_H__


#include "../CoreMacro.h"

NS_CC_CORE_BEGIN

template<typename T>
class LStaticArray
{
public:
	inline
		LStaticArray( ) : 
		m_pData(0) , 
		m_iLenght(0) , 
		m_iMaxLenght(0),
		m_iStart(0),
		m_iCurr(0)
		{ }

	inline 
		virtual ~LStaticArray( ){ clearData(); clear(); };

	inline
	static LStaticArray<T>* create( int size = 8 )
	{
		LStaticArray<T>* pArr = new LStaticArray( );
		pArr->init(size);

		return pArr;
	}

	inline 
		void			init				( int size = 8 )
		{
			if( size == m_iMaxLenght ){
				clearData( );
			}else{
				clear( );

				m_pData = new T*[size];
				m_iLenght = 0;
				m_iMaxLenght = size;

				for( int i = 0 ; i < m_iMaxLenght ; ++i ){
					m_pData[i] = 0;
				}
				
			}
		}

	inline
		void			addObject			( T* pObject )
	{
		if( m_iLenght >= m_iMaxLenght )
		{
			T** tempArr = new T*[2*m_iMaxLenght];

			memcpy( tempArr , m_pData , 2 * m_iMaxLenght * sizeof(T*) );
			delete []m_pData;

			m_pData = tempArr;

			m_iMaxLenght *= 2;
		}

		m_pData[m_iLenght++] = pObject;
	}

	//It return data if we dont release it otherwise it return NULL;
	inline
		T*			removeObject		( T* pObject , bool isRelease = true )
	{
		T* pData = 0;
		if( m_pData ){
			for(int i = 0 ; i < m_iLenght ; ++i ){
				if( m_pData[i] == pObject ){

					if( isRelease ){
						do{
							delete m_pData[i];
							m_pData[i] = 0;
						}while(0);
					}else
						pData = m_pData[i];

					m_iLenght -= 1;

					//Loop helper
					m_iCurr -= 1;

					unsigned int remain = m_iLenght - i;
					if( m_iLenght > 0 ){
						memmove( (void*)&m_pData[i] , (void*)&m_pData[i+1] , remain * sizeof(T*) ); 
					}
					
					break;
				}
			}
		}

		return pData;
	}

	//It return data if we dont release it otherwise it return NULL;
	inline
		T*			removeObjectAtIndex	( int index , bool isRelease = true )
	{
		T* pData = 0;
		if( m_pData ){
			for(int i = 0 ; i < m_iLenght ; ++i ){
				if( i == index ){

					if( isRelease ){
						do{
							delete m_pData[i];
							m_pData[i] = 0;
						}while(0);
					}else
					{
						pData = m_pData[i];
						m_pData[i] = 0;
					}

					m_iLenght -= 1;


					//Loop helper
					m_iCurr -= 1;

					unsigned int remain = m_iLenght - i;
					if( m_iLenght > 0 ){
						memmove( (void*)&m_pData[i] , (void*)&m_pData[i+1] , remain * sizeof(T*) );  
					}
					
					break;
				}
			}
		}

		return pData;
	}

	inline
		T*				getObject			( int index )
	{
		return ( index >= 0 && index < m_iLenght ) ? m_pData[index] : 0;
	}

	inline
		void			exchange			( int indexA , int indexB )
	{
		if( checkOutOfRange(indexA) || checkOutOfRange(indexB) )
			return;

		T* temp = m_pData[indexA];
		m_pData[indexA] = m_pData[indexB];
		m_pData[indexB] = temp;
	}

	inline
		bool			checkOutOfRange		( int index )
	{
		return !( index >= 0 && index < m_iLenght );
	}

	inline
		bool			containsObject		( T* pObject )
	{
		if( m_pData ){
			for( int i = 0 ; i < m_iLenght ; ++i )
			{
				if( m_pData[i] == pObject )
					return true;
			}
		}

		return false;
	}

	inline 
		void			clear				( )
		{
			if( m_pData ){
				do{
					delete []m_pData;
					m_pData = 0;
				}while(0);
			}
		}

	inline
		void			clearData			( bool isRelease = true )
	{
		if( m_pData ){
			for( int i = 0 ; i < m_iLenght ; ++i ){
				if( m_pData[i] ){
					do{
						if( isRelease )
							delete m_pData[i];
						m_pData[i] = 0;
					}while(0);
				}
			}
		}
	}

	inline
		int				count				( )
	{
		return m_iLenght;
	}

	inline
		int				capacity			( )
	{
		return m_iMaxLenght;
	}

	inline
		int				begin				( )
	{
		m_iStart = 0;
		m_iCurr = 0;
		return m_iStart;
	}

	inline
		int				end					( )
	{
		return m_iLenght;
	}

	inline
		int				next				( )
	{
		return ++m_iCurr;
	}

	inline
		void			copy				( LStaticArray<T>& pArr )
	{
		int count = pArr.count( );
		for( int i = 0 ; i < count ; ++i )
		{
			m_pData[i] = pArr.getObject(i);
		}
	}

private:
	T**			m_pData;
	int			m_iLenght;
	int			m_iMaxLenght;

	int			m_iStart;
	int			m_iCurr;
};


NS_CC_CORE_END

#endif